<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>包围盒计算测试</title>
    <script type="text/javascript" src="../doc/asset/js/esl/esl.js"></script>
</head>
<body>
    <div id="Main"></div>
</body>
    <script type="text/javascript">
    require.config({
        packages: [
            {
                name: 'zrender',
                location: '../src',
                main: 'zrender'
            }
        ]
    });
        
    require(['zrender',
            'zrender/tool/util',
            'zrender/tool/computeBoundingBox'], 
        function(zrender, util, computeBoundingBox){
            var canvas = document.createElement('canvas')
            document.getElementById("Main").appendChild(canvas);
            canvas.width = 1024;
            canvas.height = 600;
            if (G_vmlCanvasManager) {
             G_vmlCanvasManager.initElement(canvas);
            }
            var ctx = canvas.getContext("2d");
            modifyCtx(ctx, util);

            ctx.beginPath();
            ctx.moveTo(20, 20);
            ctx.bezierCurveTo(100, 0, -100, 100, 100, 100);
            ctx.quadraticCurveTo(400, 10, 200, 200);

            ctx.arc(200, 200, 50, 1, 3, true);
            ctx.stroke();

            var bb = ctx.getPathBoundingRect();
            ctx.beginPath();
            ctx.strokeRect(bb.left, bb.top, bb.right-bb.left, bb.bottom-bb.top);

            function modifyCtx(ctx, util){
                var ctxMoveTo = ctx.moveTo;
                var ctxLineTo = ctx.lineTo;
                var ctxBezierCurveTo = ctx.bezierCurveTo;
                var ctxQuadraticCurveTo = ctx.quadraticCurveTo;
                var ctxArc = ctx.arc;
                var ctxBeginPath = ctx.beginPath;

                var min = [];
                var max = [];

                function updateBoundingBox(){
                    ctx._boundingBox.min[0] = Math.min(min[0], ctx._boundingBox.min[0]);
                    ctx._boundingBox.min[1] = Math.min(min[1], ctx._boundingBox.min[1]);
                    ctx._boundingBox.max[0] = Math.max(max[0], ctx._boundingBox.max[0]);
                    ctx._boundingBox.max[1] = Math.max(max[1], ctx._boundingBox.max[1]);
                }
                ctx.getPathBoundingRect = function(){
                    var bb = ctx._boundingBox;
                    return {
                        left : bb.min[0],
                        top : bb.min[1],
                        right : bb.max[0],
                        bottom : bb.max[1]
                    }
                }
                ctx.beginPath = function(){
                    ctx._current = [0, 0];
                    ctx._boundingBox = {
                        min : [999999, 9999999], 
                        max : [-9999999, -9999999]
                    };
                    ctxBeginPath.call(this);
                }

                ctx.moveTo = function(x, y) {
                    ctx._current[0] = x;
                    ctx._current[1] = y;
                    ctxMoveTo.call(this, x, y);
                }

                ctx.lineTo = function(x, y) {
                    computeBoundingBox([ctx._current, [x, y]], min, max);
                    updateBoundingBox();                
                    ctx._current[0] = x;
                    ctx._current[1] = y;
                    ctxLineTo.call(this, x, y);
                }

                ctx.bezierCurveTo = function(x0, y0, x1, y1, x2, y2) {
                    computeBoundingBox.cubeBezier(
                        ctx._current,
                        [x0, y0],
                        [x1, y1],
                        [x2, y2],
                        min, max
                    );
                    updateBoundingBox();
                    ctx._current[0] = x2;
                    ctx._current[1] = y2;
                    ctxBezierCurveTo.call(this, x0, y0, x1, y1, x2, y2);
                }

                ctx.quadraticCurveTo = function(x0, y0, x1, y1) {
                    computeBoundingBox.quadraticBezier(
                        ctx._current,
                        [x0, y0],
                        [x1, y1],
                        min, max
                    );
                    updateBoundingBox();
                    ctx._current[0] = x1;
                    ctx._current[1] = y1;
                    ctxQuadraticCurveTo.call(this, x0, y0, x1, y1);
                }

                ctx.arc = function(x, y, radius, startAngle, endAngle, anticlockwise) {
                    computeBoundingBox.arc(
                        x, y,
                        radius,
                        startAngle,
                        endAngle,
                        anticlockwise,
                        min, max
                    );

                    updateBoundingBox();

                    ctxArc.call(this, x, y, radius, startAngle, endAngle, anticlockwise);
                }
            }
        }
    );
    </script>
</html>